package org.zjt.demo.service.imp;

import org.springframework.remoting.RemoteAccessException;
import org.springframework.retry.RecoveryCallback;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.retry.backoff.FixedBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.stereotype.Service;

import java.util.Collections;

/**
 * Created by Administrator on 2017/5/16.
 */
@Service
public class RetryService2 {


    public void service() {

        // TODO: 2017/5/17  可以将 retryTemplate放在spring IOC中，执行全局的重试。
        final RetryTemplate retryTemplate = new RetryTemplate();
        final SimpleRetryPolicy policy = new SimpleRetryPolicy(3, Collections.<Class<? extends Throwable>, Boolean>singletonMap(Exception.class, true));
        FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
        fixedBackOffPolicy.setBackOffPeriod(100);
        retryTemplate.setRetryPolicy(policy);
        retryTemplate.setBackOffPolicy(fixedBackOffPolicy);

        /*
        final RetryCallback<Object, Exception> retryCallback = (RetryContext context) -> {

            System.out.println("do some thing");
            System.out.println("--------------------此处利用aop实现对代码实现乐观锁拦截、幂等接口的重试调用--------------------");

            //设置context一些属性,给RecoveryCallback传递一些属性
            context.setAttribute("key1", "value1");
            System.out.println(context.getRetryCount());
            int i = 1 / 0;

            // TODO: 2017/5/17 AOP执行正常返回的执行结果。
            return null;
        };


        // 如果RetryCallback执行出现指定异常, 并且超过最大重试次数依旧出现指定异常的话,就执行RecoveryCallback动作
        final RecoveryCallback<Object> recoveryCallback = (RetryContext context) -> {
            System.out.println(String.format("重试%s次，do recory operation", context.getRetryCount()));
            System.out.println(context.getAttribute("key1"));
            System.out.println(context.getLastThrowable().getMessage());

            // TODO: 2017/5/17 AOP执行失败，返回的结果
            return null;
        };

        */


        try {
            final Object execute = retryTemplate.execute((RetryContext context) -> {

                System.out.println("do some thing");
                System.out.println("--------------------此处利用aop实现对代码实现乐观锁拦截、幂等接口的重试调用--------------------");

                //设置context一些属性,给RecoveryCallback传递一些属性
                context.setAttribute("key1", "value1");
                System.out.println(context.getRetryCount());
                int i = 1 / 0;

                // TODO: 2017/5/17 AOP执行正常返回的执行结果。
                return null;
            }, (RetryContext context) -> {
                System.out.println(String.format("重试%s次，do recory operation", context.getRetryCount()));
                System.out.println(context.getAttribute("key1"));
                System.out.println(context.getLastThrowable().getMessage());

                // TODO: 2017/5/17 AOP执行失败，返回的结果
                return null;
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}